package cz.vse.po1715.lode.net.obecne;

import cz.vse.po1715.lode.net.klient.AKlient;
import java.util.*;
import java.io.*;
import java.util.logging.*;

/**
 * Instance třídy {@code SpravcePrikazu} představují načítače
 * uživatelských vstupů z konzole, které tyto vstupy zpracovávají a předávají
 * je klientům k odeslání na server.
 * @author  Dominik KOSTKA
 * @version 0.00.00
 */
public class SpravcePrikazu extends Thread {
    /** logger */
    private Logger log = Logger.getLogger("NačítačUdálostíKonzole");

    /** odkaz na klienta */
    private AKlient klient;

    /** fronta příchozích udalostí */
    private FrontaUdálostí vstupniFronta;
    
    /** fronta odchozích událostí */
    private FrontaUdálostí vystupniFronta;

    /** příznak spuštění vlákna */
    private  boolean bezici;
    
    /** text zobrazovaný nově připojeným hráčům */
    private static final String VITAME_VAS =
            "\n\nVitejte ve hre Lode, viceuzivatelske sitove hre\n\n";

    /** text nápovědy*/
    private static final String TEXT_NAPOVEDA =
	"prikazy hry:\n" +
	"'/odpoj'\t\t\t\t\t odpoji hrace ze serveru \n" +
	"'/help'\t\t\t\t\t ukaze tuto napovedu \n" +
	"'/hraci'\t\t\t\t zobrazi seznam hracu online\n" +
	"'/hra <id souper>'\t\t zacne novou hru proti zadanemu souperi\n" +
	"'/utok <pole>'\t provede vas utok na zadane policko hraciho pole\n" +
        "'/lod <typlode> <souradnice> <smer>'\t " +
        "vytvori lod daneho typu, na danych souradnicich\n" +
        "s danym smerem natoceni (mozne pouzit jen pred zacatkem hry)" +
	"'/konec' \t\t\t\t ukonci hru\n" +
	"Vsechny ostatni vstupy jsou povazovane za zpravy chatu.\n";

    /** 
     * 
     */
    public SpravcePrikazu
            (AKlient klient, FrontaUdálostí vstupniFronta, FrontaUdálostí vystupniFronta)
    {
	super("NacitacUdalostiKonzole");
	this.klient = klient;
	this.vstupniFronta = vstupniFronta;
	this.vystupniFronta = vystupniFronta;
    }

    @Override
    public void run() {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	System.out.println(VITAME_VAS + TEXT_NAPOVEDA);
			
	bezici = true;
	while (bezici) {
	    try {
		String radek = br.readLine();
		String parametry[] = parametrizujString(radek);
		if (parametry.length > 0) {
		    IHerniUdalost udalost = rozeberVstup(parametry, radek);
		    if (udalost != null) {
			vystupniFronta.pridej(udalost);
		    }
		}
		else {
		    klient.stdVystup(null);
		}
	    }
	    catch (Exception ioe) {
		log.info("vyjimka behem nacitani uzivatelskeho vstupu do " +
                        "herni udalosti");
	    }
	}
    }  

    public void vypni() {
	bezici = false;
	interrupt();
    }

    private IHerniUdalost rozeberVstup(String parametry[], String line) {
	parametry[0] = parametry[0].toLowerCase();

	IHerniUdalost událost = null;
	if (parametry[0].equals("/odpoj")) {
	    událost = new HerniUdalost(HerniUdalost.K_ODPOJENÍ, "Nashledanou!");
	}
	else if (parametry[0].equals("/help") || parametry[0].equals("?")) {
	    klient.stdVystup(TEXT_NAPOVEDA);
	}
	else if (parametry[0].equals("/hraci")) {
	    událost = new HerniUdalost(HerniUdalost.K_GET_HRÁČI);
	}
	else if (parametry[0].equals("/hra")) {
	    if (parametry.length < 2)
		spatnyCmd(parametry, "nebyl zadan souper");
	    else {
		událost = new HerniUdalost(HerniUdalost.K_PŘIHLÁŠENÍ_HRA, parametry[1]);
		klient.setSoupeř(parametry[1]);
	    }
	}
	else if (parametry[0].equals("/utok")) {
	    if (parametry.length != 2)
		spatnyCmd(parametry, "neplatny uder: spatny format prikazu");
	    else
		událost = new HerniUdalost(HerniUdalost.K_UDER, parametry[1]);
	}
	else if (parametry[0].equals("/konec")) {
	    událost = new HerniUdalost(HerniUdalost.K_ODHLÁSIT_HRA);
	}
        else if (parametry[0].equals("/lod")) {
            if (parametry.length != 4){
		spatnyCmd(parametry, "neplatne rozmistovani lodi: spatny format " +
                        "prikazu");
	    }else
                událost = new HerniUdalost(HerniUdalost.K_UMISTI_LOD,
                        spojStringy(parametry));
	}
	else {
	    událost = new HerniUdalost(HerniUdalost.K_CHAT_ZPRÁVA, line.trim());
	    klient.stdVystup(null);
	}
	return událost;
    }

    private String spojStringy(String parametry[]){
        StringBuffer sb = new StringBuffer();

        for(int i = 1; i <parametry.length; i++){
            sb.append(parametry[i]);
            if(i < parametry.length -1) sb.append(" ");
        }
        return sb.toString();
    }

    private void spatnyCmd(String parametry[], String zprava) {
	vstupniFronta.pridej(new HerniUdalost(HerniUdalost.K_CMD_ACK, zprava));
    }

    public static String[] parametrizujString(String s) {
	StringTokenizer parametrizer = new StringTokenizer(s, " ");
	int pocet = parametrizer.countTokens();
	
	String[] parametry = new String[pocet];
	
	for (int i=0; parametrizer.hasMoreTokens(); i++) {
	    parametry[i] = parametrizer.nextToken();
	}
	return parametry;
    }
}


